package Server;

import CommonOperationsClientServer.FilesOperations;
import CommonOperationsClientServer.OperationsRefactor;
import Users.User;
import java.io.*;
import java.net.ServerSocket;

public class FilesOperationsServer {

    public static void initializeServerFiles(String directoryFather, String directoryUsersNoPrivileged,
            String directoryServerInfo, String usersFile, String serverLog, String serverConfigurationFile) {
        File father = new File(directoryFather);
        if (father.exists() && father.isDirectory()) {
            createFolder(directoryUsersNoPrivileged);
            createFolder(directoryServerInfo);
            FilesOperations.createFile(usersFile);
            FilesOperations.createFile(serverConfigurationFile);
            FilesOperations.createFile(serverLog);
            User user = new User("root", "toor", true);
            UsersOperationsServer.createNewUser(user, usersFile, null, null, true);
        } else {
            //@Abraham comprobar valor de retorno
            father.mkdir();
            initializeServerFiles(directoryFather, directoryUsersNoPrivileged, directoryServerInfo, usersFile,
                    serverLog, serverConfigurationFile);
        }
    }
//@Abraham un mtodo como este debería asumir que puede ser imposible cumplir su tarea
    public static void deleteFolder(String directory, PrintWriter output, boolean recursion) {
        File f = new File(directory);
        boolean deleted;
        if (f.exists()) {
            if (f.isDirectory()) {
                File[] files = f.listFiles();
                for (int i = 0; i < files.length; i++) {
                    deleteFolder(files[i].getAbsolutePath(), output, true);
                }
                deleted = f.delete();
                if (!recursion) {
                    if (deleted) {
                        OperationsRefactor.outputMessage(output, "folderdeleted");
                    } else {
                        OperationsRefactor.outputMessage(output, "foldernotdeleted");
                    }
                }
            } else {
                if (!recursion) {
                    OperationsRefactor.outputMessage(output, "notfolderselected");
                } else {
                    //@Abraham Este método devuelve algo, Y en base a lo que devuelve deberías poder mandar un mensaje de error
                    f.delete();
                }
            }
        } else {
            if (!recursion) {
                OperationsRefactor.outputMessage(output, "foldernotfound");
            }
        }
    }

    public static boolean deleteFile(String file, PrintWriter output) {
        File f = new File(file);
        boolean success = false;
        if (f.exists()) {
            if (f.isFile()) {
                //@Abraham ¡milagro! Aqu sí que te acordaste!
                success = f.delete();
                if (success) {
                    OperationsRefactor.outputMessage(output, "filedeleted");
                } else {
                    OperationsRefactor.outputMessage(output, "notfiledeleted");
                }
            } else {
                OperationsRefactor.outputMessage(output, "notfileselected");
            }
        } else {
            OperationsRefactor.outputMessage(output, "filenotfound");
        }
        return success;
    }

    private static void createFolder(String folderName) {
        File folder = new File(folderName);
        if (!folder.exists() || !folder.isDirectory()) {
            //@Abraham Este método devuelve algo importante
            folder.mkdir();
        }
    }

    public static void createFolder(String directoryFather, String folderName, PrintWriter output) {
        File folderFather = new File(directoryFather);
        if (folderFather.exists() && folderFather.isDirectory()) {
            File folder = new File(directoryFather, folderName);
            if (!folder.exists()) {
                boolean create = folder.mkdir();
                if (create) {
                    OperationsRefactor.outputMessage(output, "foldercreated");
                } else {
                    OperationsRefactor.outputMessage(output, "foldernotcreated");
                }
            } else {
                OperationsRefactor.outputMessage(output, "folderexists");
            }
        } else {
            OperationsRefactor.outputMessage(output, "notdirectoryselected");
        }
    }

    public static void directoryFiles(String directory, PrintWriter output) {
        try {
            File file = new File(directory);
            if (file.isDirectory()) {
                File[] files = file.listFiles(new FileFilter() {

                    @Override
                    public boolean accept(File pathname) {
                        return true;
                    }
                });
                for (int i = 0; i < files.length; i++) {
                    OperationsRefactor.outputMessage(output, files[i].getAbsolutePath());
                }
            }
        } catch (Exception e) {
        }
        OperationsRefactor.outputMessage(output, "listOfDirectoriesEnd");
    }

    public static void sendInfoFromLocalFile(String directory, PrintWriter output) {
        String permissions = FilesOperations.getInfoFromLocalFile(directory);
        OperationsRefactor.outputMessage(output, permissions);
    }

    public static void uploadFile(String fileName, String directoryDestination, boolean usersPermissions,
            String directoryUsersNoPrivileged, BufferedReader input, PrintWriter output) {
        File directory = new File(directoryDestination);
        if (directory.isDirectory()) {
            if ((usersPermissions == false) && !directoryDestination.contains(directoryUsersNoPrivileged)) {
                OperationsRefactor.outputMessage(output, "notPrivilegedDirectory");
            } else {
                OperationsRefactor.outputMessage(output, "OK");
                FilesOperations.receiveFile(directoryDestination, fileName, input);
            }
        } else {
            OperationsRefactor.outputMessage(output, "notFolderSelected");
        }
    }

    public static void downloadFile(String file, String directoryUsersNoPrivileged, boolean usersPermissions,
            BufferedReader input, PrintWriter output) {
        File f = new File(file);
        if (f.isFile()) {
            if ((usersPermissions == false) && !file.contains(directoryUsersNoPrivileged)) {
                OperationsRefactor.outputMessage(output, "notPrivilegedFile");
            } else {
                OperationsRefactor.outputMessage(output, "OK");
                OperationsRefactor.outputMessage(output, f.getName());
                FilesOperations.sendFile(f, output);
            }
        } else {
            OperationsRefactor.outputMessage(output, "notFileSelected");
        }
    }

    public static void updateServerConfiguration(String serverConfigFile, String serverLogPath) {
        File f = new File(serverConfigFile);
        FileWriter fw = null;
        PrintWriter pw = null;
        try {
            //@Abraham comprobar valor de retorno
            f.delete();
            fw = new FileWriter(f);
            pw = new PrintWriter(fw);
            pw.println("PortServer:" + StartCloseServer.getPortServer());
            pw.println("ServerDirectory:" + StartCloseServer.getServerDirectory());
            pw.println("ServerConfigurationDirectory:" + StartCloseServer.getServerConfigurationDirectory());
            pw.println("ServerConfigurationFile:" + StartCloseServer.getServerConfigurationFile());
            pw.println("UsersFile:" + StartCloseServer.getUsersFile());
            pw.println("UsersNoPrivilegedDirectory:" + StartCloseServer.getUsersNoPrivilegedDirectory());
            pw.println("ServerLog:" + serverLogPath);
            StartCloseServer.setServerLog(serverLogPath);
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            OperationsRefactor.closeWriteFile(fw, pw);
        }
    }

    public static void sendServerConfiguration(PrintWriter output, ServerSocket socket) {
        String allDirectories = socket.getInetAddress().getHostAddress().toString() + ";"
                + socket.getLocalPort() + ";"
                + StartCloseServer.getServerDirectory() + ";"
                + StartCloseServer.getServerConfigurationDirectory() + ";"
                + StartCloseServer.getServerConfigurationFile() + ";"
                + StartCloseServer.getServerLog() + ";"
                + StartCloseServer.getUsersFile() + ";"
                + StartCloseServer.getUsersNoPrivilegedDirectory();
        OperationsRefactor.outputMessage(output, allDirectories);
    }

    public static void moveServerLog(String serverConfigFile, String logDestiny, PrintWriter output) {
        String logSource = getServerLogPath(serverConfigFile, serverConfigFile, serverConfigFile);
        File fSource = new File(logSource);
        File fDestiny = new File(logDestiny);
        if (!logSource.equals(logDestiny)) {
            if (!fDestiny.exists()) {
                try {

                    boolean rename = fSource.renameTo(fDestiny);
                    updateServerConfiguration(serverConfigFile, fDestiny.getAbsolutePath());
                    if (rename) {
                        OperationsRefactor.outputMessage(output, "moveServerLogOK");
                    }
                } catch (Exception e) {
                    OperationsRefactor.outputMessage(output, "moveServerLogFail");
                }
            } else {
                OperationsRefactor.outputMessage(output, "invalidName");
            }
        } else {
            OperationsRefactor.outputMessage(output, "equalsLogs");
        }
    }

    public static String getServerLogPath(String serverConfigFile, String serverConfigDirectory,
            String serverlog) {
        File f = new File(serverConfigFile);
        String serverLogPath = "";
        if (f.exists()) {
            FileReader fr = null;
            BufferedReader br = null;
            try {
                fr = new FileReader(f);
                br = new BufferedReader(fr);
                String line;
                boolean continueRead = true;
                while ((line = br.readLine()) != null && continueRead) {
                    if (line.contains("ServerLog:")) {
                        int position = line.lastIndexOf(":");
                        line = line.substring(position + 1);
                        if ((line != null) && !line.equals("")) {
                            serverLogPath = line;
                        } else {
                            serverLogPath = serverConfigDirectory + serverlog;
                        }
                        continueRead = false;
                    }
                }
            } catch (Exception e) {
            } finally {
                OperationsRefactor.closeReadFile(fr, br);
            }
        } else {
            serverLogPath = serverConfigDirectory + serverlog;
        }
        return serverLogPath;
    }
}
